package org.crystalrange.files.web;

import java.util.Date;
import java.util.List;
import java.util.Set;

import org.apache.commons.io.IOUtils;
import org.crystalrange.BaseController;
import org.zkoss.util.media.Media;
import org.crystalrange.files.model.File;
import org.crystalrange.files.service.FileService;
import org.crystalrange.files.service.FileTypeService;
import org.crystalrange.model.User;
import org.crystalrange.service.UserService;
import org.springframework.security.core.context.SecurityContextHolder;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zul.Filedownload;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Window;

import com.googlecode.genericdao.search.Search;

public class FileListController extends BaseController {

	protected File selectedFile;
	protected FileService fileService;
	protected List<File> files;
	protected Listbox listboxFile;
	protected Search searchFile;
	private UserService userService;
	private FileTypeService fileTypeService;

	public File getSelectedFile() {
		return selectedFile;
	}

	public void setSelectedFile(File selectedFile) {
		this.selectedFile = selectedFile;
	}

	public FileService getFileService() {
		return fileService;
	}

	public void setFileService(FileService fileService) {
		this.fileService = fileService;
	}

	public List<File> getFiles() {
		return files;
	}

	public void setFiles(List<File> files) {
		this.files = files;
	}
	
	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	
	public FileTypeService getFileTypeService() {
		return fileTypeService;
	}

	public void setFileTypeService(FileTypeService fileTypeService) {
		this.fileTypeService = fileTypeService;
	}

	public void onClick$toolbarbuttonFileEdit(Event event) throws Exception {
		this.fileEdit();
	}

	public void onClick$menuitemFileEdit(Event event) throws Exception {
		this.fileEdit();
	}

	public void onClick$toolbarbuttonFileDelete(Event event) throws Exception {
		this.fileDelete();
	}

	public void onClick$menuitemFileDelete(Event event) throws Exception {
		this.fileDelete();
	}

	public void onClick$toolbarbuttonFileSearch(Event event) throws Exception {
		this.fileSearch();
	}

	public void onClick$menuitemFileSearch(Event event) throws Exception {
		this.fileSearch();
	}

	public void onClick$toolbarbuttonFileRefresh(Event event) throws Exception {
		this.fileRefresh();
	}

	public void onClick$menuitemFileRefresh(Event event) throws Exception {
		this.fileRefresh();
	}

    public void onUpload$toolbarbuttonFileUpload(UploadEvent event) throws Exception {
        this.fileUpload(event);
    }
    
    public void onUpload$menuitemFileUpload(UploadEvent event) throws Exception {
		this.fileUpload(event);
	}

    public void onClick$toolbarbuttonFileDownload(Event event) throws Exception {
        this.fileDownload();
    }
    
    public void onClick$menuitemFileDownload(Event event) throws Exception {
        this.fileDownload();
    }

	@Override
	public void doAfterCompose(Component component) throws Exception {
		super.doAfterCompose(component);
		this.searchFile = new Search(File.class);
		this.searchFile.setMaxResults(100);
		this.searchFile.addFetch("createdBy");
		this.files = this.fileService.search(this.searchFile);
		component.setAttribute("controller", this);
	}

	private void fileEdit() throws Exception {
		if (this.selectedFile != null) {
			this.execution.sendRedirect("~./zul/html/file.zul?Id="
					+ this.selectedFile.getId().toString());
		}
	}

	private void fileDelete() throws Exception {
		Set<Listitem> selectedItems = this.listboxFile.getSelectedItems();

		if (selectedItems.size() > 0) {
			if (Messagebox.YES == Messagebox.show("Delete these records?",
					"Delete?", Messagebox.YES | Messagebox.NO,
					Messagebox.QUESTION)) {
				for (Listitem selectedItem : selectedItems) {
					File file = (File) selectedItem.getValue();
					this.fileService.remove(file);
				}
				this.selectedFile = null;
			}
		} else {
			this.message.setText("Please select at least one item!");
			this.message.setIcon("/img/exclamation.png");
		}
		this.files = this.fileService.search(this.searchFile);
		this.binder.loadAll();
	}

	private void fileSearch() throws Exception {
		this.execution.setAttribute("searchFile", this.searchFile);

		Window window = (Window) this.execution.createComponents(
				"~./zul/html/fileSearch.zul", null, null);
		window.setParent(self);
		window.doModal();

		if (this.execution.getAttribute("result") == "ok") {
			this.searchFile = (Search) this.execution
					.getAttribute("searchFile");
		}

		this.files = this.fileService.search(this.searchFile);
		this.binder.loadAll();
	}

	private void fileRefresh() throws Exception {
		this.files = this.fileService.search(this.searchFile);
		this.binder.loadAll();
	}
	
    private void fileUpload(UploadEvent event) throws Exception {
       
        Media media = (Media) event.getMedia();
        
        if (media != null) {
        	
        	String username = SecurityContextHolder.getContext()
    				.getAuthentication().getName();
    		User currentUser = this.userService.findByUsername(username);

    		byte[] content = IOUtils.toByteArray(media.getStreamData());
    		    		
    		File file = new File();
    		file.setCreatedBy(currentUser);
    		file.setCreatedDate(new Date());
            file.setContentType(media.getContentType());
            file.setName(media.getName());
			file.setContent(content);
			file.setSize((long) content.length);
			
			int dotPos = file.getName().lastIndexOf(".");
    		String extension = file.getName().substring(dotPos);
    		Search search = new Search();
    		search.addFilterEqual("extension", extension);
    		
    		file.setFileType(this.fileTypeService.searchUnique(search));
    		if (file.getFileType() != null) {
    			this.fileService.save(file);
    		} else {
    			this.message.setText("There is no defined file type for the extension '" + extension.toString() + "'.");
                this.message.setIcon("/img/exclamation.png");
    		}
        }

        this.files = this.fileService.search(this.searchFile);
		this.binder.loadAll();
    }

    private void fileDownload() throws Exception {
    	if (this.selectedFile != null)
    	{
    		Filedownload.save(
				this.selectedFile.getContent(), 
				this.selectedFile.getContentType(), 
				this.selectedFile.getName());
        } else {
            this.message.setText("Please select at least one item!");
            this.message.setIcon("/img/exclamation.png");
        }

        this.files = this.fileService.search(this.searchFile);
		this.binder.loadAll();
    }

}
